package com.rbac.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.domain.dto.PageDTO;
import com.domain.dto.permission.PermissionDTO;
import com.domain.dto.role.*;
import com.domain.query.role.RoleQuery;
import com.rbac.mapper.PermissionMapper;
import com.rbac.mapper.RoleMapper;
import com.rbac.pojo.Permission;
import com.rbac.pojo.Role;
import com.rbac.service.IRoleService;
import org.mapstruct.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Mapper(componentModel = "spring")
interface msRoleMapper{
    Role addRoleToRole(AddRoleDTO addRoleDTO);
    Role modifyRoleToRole(ModifyRoleDTO modifyRoleDTO);
    RoleDTO RoleToRoleDTO(Role Role);
}
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Autowired
    msRoleMapper msRoleMapper;
    @Autowired
    msPermissionMapper msPermissionMapper;
    @Autowired
    PermissionMapper permissionMapper;
    @Autowired
    RoleMapper roleMapper;
    //查询角色列表
    @Override
    public PageDTO<RoleDTO> queryRoleList(RoleQuery roleQuery) {
        Page<Role> page = new Page<>(roleQuery.getPageIndex(), roleQuery.getPageSize());
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        if(roleQuery.getRoleId() != null){
            wrapper.eq("role_id",roleQuery.getRoleId());
        }
        Page<Role> result = baseMapper.selectPage(page, wrapper);

        return PageDTO.create(result, msRoleMapper::RoleToRoleDTO);
    }

    //根据roleId查询角色
    @Override
    public RoleDTO queryRoleByRoleId(Integer roleId) {
        return msRoleMapper.RoleToRoleDTO(baseMapper.selectById(roleId));
    }

    //添加角色
    @Override
    public Integer addRole(AddRoleDTO addRoleDTO) {
        //将dto数据转换成do数据
        Role role = msRoleMapper.addRoleToRole(addRoleDTO);
        System.out.println(role);
        //添加数据
        int addedRow = baseMapper.insert(role);
        //TODO 添加默认权限默认查看权限，默认permissionId值为1
        int row = this.addRolePermission(role.getRoleId(), 1);
        return addedRow;
    }

    //修改角色
    @Override
    public Integer modifyRole(ModifyRoleDTO modifyRoleDTO) {
        //将dto数据转换成do数据
        Role modifyRole = msRoleMapper.modifyRoleToRole(modifyRoleDTO);
        System.out.println(modifyRole);

        //修改数据并返回修改的行数
        return baseMapper.updateById(modifyRole);
    }

    //删除用户
    @Override
    public Integer removeRole(List<Integer> roleIds) {
        int totalDeletedRow = 0;
        for(Integer roleId : roleIds){
            //删除角色用户表数据
            int row1 = this.removeRoleUser(roleId);
            //删除角色权限表数据
            int row2 = this.removeRolePermission(roleId);
            //删除角色表数据
            int deletedRow = baseMapper.deleteById(roleId);
            totalDeletedRow += deletedRow;
        }
        //批量删除角色表数据
        //baseMapper.deleteRoles(roleIds);
        //返回删除的角色表的总行数
        return totalDeletedRow;
    }

    //根据roleId查询拥有用户名称列表
    @Override
    public List<String> queryUserNameListByRoleId(Integer roleId) {
        return baseMapper.queryUserNameListByRoleId(roleId);
    }

    //根据roleId查询角色拥有权限名称列表
    @Override
    public List<String> queryPermissionNameListByRoleId(Integer roleId) {
        return baseMapper.queryPermissionNameListByRoleId(roleId);
    }

    //根据角色id来修改角色权限
    @Override
    public Integer modifyRolePermission(ModifyRolePermissionDTO modifyRolePermissionDTO) {
        int roleId = modifyRolePermissionDTO.getRoleId();
        List<Integer> permissionIds = modifyRolePermissionDTO.getPermissionIds();

        //删除roleId的权限
        int deletedRow = this.removeRolePermission(roleId);

        //添加角色id对应的权限
        int totalAddedRow = 0;
        for(Integer permissionId : permissionIds){
            int addedRow = this.addRolePermission(roleId, permissionId);
            totalAddedRow +=addedRow;
        }
        return totalAddedRow;
    }

    //根据角色id来查询对应的权限树
    @Override
    public List<PermissionTreeDTO> getPermissionTree(Integer roleId) {
        //查询角色对应权限
        List<Permission> permissions = baseMapper.getUserPermission(roleId);
        System.out.println(permissions);

        //将查询到的数据，转换成permissionDTO数据
        List<PermissionTreeDTO> permissionTreeDTOs = new ArrayList<>();
        for(Permission permission : permissions){
            PermissionDTO permissionDTO = msPermissionMapper.PermissionToPermissionDTO(permission);
            PermissionTreeDTO permissionTreeDTO = new PermissionTreeDTO();
            permissionTreeDTO.setPermissionDTO(permissionDTO);
            permissionTreeDTOs.add(permissionTreeDTO);
        }
        System.out.println(permissionTreeDTOs);

        //查询权限中，parentId为0的数据，设为根数据，记录自身id
        List<PermissionTreeDTO> parentList = permissionTreeDTOs.stream()
                .filter(item -> item.getPermissionDTO().getParentId() == 0)
                .toList();
        System.out.println(parentList);

        //将对应根id的子数据装入
        //递归构建菜单树
        buildPermissionTree(parentList, permissionTreeDTOs);
        System.out.println(parentList);
        return parentList;
    }


    //TODO 添加角色对应的权限
    public Integer addRolePermission(Integer roleId, Integer permissionId){
        return roleMapper.addRolePermission(roleId, permissionId);
    }

    //TODO 查询角色所对应的用户
    public List<Integer> queryRoleUserByRoleId(Integer roleId){
        return roleMapper.queryRoleUserByRoleId(roleId);
    }

    //TODO 查询角色所对应的权限
    public List<Integer> queryRolePermissionByRoleId(Integer roleId){
        return roleMapper.queryRolePermissionByRoleId(roleId);
    }

    //TODO 删除角色用户中间表数据
    public Integer removeRoleUser(Integer roleId){
        return roleMapper.removeRoleUser(roleId);
    }

    //TODO　删除角色权限中间表数据
    public Integer removeRolePermission(Integer roleId){
        return roleMapper.removeRolePermission(roleId);
    }

    private void buildPermissionTree(List<PermissionTreeDTO> permissionTreeDTOList, List<PermissionTreeDTO> permissionTreeDTOs) {
        for(PermissionTreeDTO parent : permissionTreeDTOList) {
            List<PermissionTreeDTO> children = permissionTreeDTOs.stream()
                    .filter(permissionTreeDTO -> Objects.equals(permissionTreeDTO.getPermissionDTO().getParentId(), parent.getPermissionDTO().getPermissionId()))
                    .collect(Collectors.toList());
            parent.setChildrenList(children);
            buildPermissionTree(children, permissionTreeDTOs);
        }
    }
}
